using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Reflection;
using System.Collections;

namespace SpiderService
{
	public class Types
	{
		private static Dictionary<string, Type> s_Types;
		private static FileSystemWatcher s_FileWatcher;

		static Types()
		{
			s_Types = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase);
		}

		public static Type GetType(string fullName)
		{
			lock ((s_Types as ICollection).SyncRoot)
			{
				Type type;
				s_Types.TryGetValue(fullName, out type);
				return type;
			}
		}

		public static void Init()
		{
			LoadType();
			InitFileWatcher();
		}

		private static void LoadType()
		{
			try
			{
				string[] arrFileNames = Directory.GetFiles(Globals.LibPath, "*.dll", SearchOption.AllDirectories);
				if (arrFileNames == null || arrFileNames.Length == 0)
					return;

				s_Types.Clear();

				foreach (string s in arrFileNames)
				{
					byte[] byteAssembly = File.ReadAllBytes(s);
					Assembly assembly = Assembly.Load(byteAssembly);
					if (assembly != null)
					{
						Type[] arrTypes = assembly.GetTypes();
						AssemblyName assemblyName = AssemblyName.GetAssemblyName(s);
						foreach (Type t in arrTypes)
						{
							lock ((s_Types as ICollection).SyncRoot)
							{
								s_Types.Add(t.FullName + "," + assemblyName.Name, t);
							}
						}
					}
				}
			}
			catch (Exception ex)
			{
				Globals.FileLog.WriteError(ex);
			}
		}

		private static void InitFileWatcher()
		{
			s_FileWatcher = new FileSystemWatcher(Globals.LibPath);
			s_FileWatcher.Filter = "*.dll";
			s_FileWatcher.EnableRaisingEvents = true;
			s_FileWatcher.IncludeSubdirectories = true;
			s_FileWatcher.Created += new FileSystemEventHandler(watcher_Created);
			s_FileWatcher.Changed += new FileSystemEventHandler(watcher_Changed);
			s_FileWatcher.Deleted += new FileSystemEventHandler(watcher_Deleted);
			s_FileWatcher.Renamed += new RenamedEventHandler(watcher_Renamed);
		}

		public static void Dispose()
		{
			if (s_FileWatcher != null)
			{
				s_FileWatcher.Dispose();
			}
		}

		private static void watcher_Renamed(object sender, RenamedEventArgs e)
		{
			LoadType();
		}

		private static void watcher_Deleted(object sender, FileSystemEventArgs e)
		{
			LoadType();
		}

		private static void watcher_Changed(object sender, FileSystemEventArgs e)
		{
			LoadType();
		}

		private static void watcher_Created(object sender, FileSystemEventArgs e)
		{
			LoadType();
		}
	}
	
}
